<?php

class Models extends Model
{
    public function findAll($model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
            if(!$model) return false;
        }
        $query=$this->db->query("SELECT * FROM `".DB_PREFIX.$model."`");
        if(!isset($query->rows) || !$query->rows) return false;

        return $query->rows;
    }

    public function findByPk($pk=0, $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }

        if(!$pk){
            $pk=isset($this->id) ? $this->id : (isset($this->Id) ? $this->Id : $this->getPk());
        }
        if(!$pk || !$model || $this->isEmpty($model)) return false;

        $query=$this->db->query("SELECT * FROM `".DB_PREFIX.$model."` WHERE ".$this->getPk($model)." = '".(int)$pk."'");

        if(!isset($query->rows) || !$query->row) return false;

        return $query->row;
    }

    public function findByAttributes($attributes=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$attributes || !$model) return null;
        $sql="SELECT * FROM `".DB_PREFIX.$model."` WHERE ";

        $attributesNames=array_keys($attributes);
        foreach($attributes as $name=>$attr){
            if($name!=end($attributesNames)){
                $sql.=$name." = '".$attr."' AND ";
            }else{
                $sql.=$name." = '".$attr."'";
            }
        }

        $query=$this->db->query($sql);
        if(!isset($query->row) || !$query->row) return false;

        return $query->row;
    }

    public function findAllByAttributes($attributes=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$attributes || !$model) return null;
        $sql="SELECT * FROM `".DB_PREFIX.$model."` WHERE ";

        $attributesNames=array_keys($attributes);
        foreach($attributes as $name=>$attr){
            if($name!=end($attributesNames)){
                $sql.=$name." = '".$attr."' AND ";
            }else{
                $sql.=$name." = '".$attr."'";
            }
        }

        $query=$this->db->query($sql);

        if(!isset($query->rows) || !$query->rows) return false;

        return $query->rows;
    }

    public function findAllModelAttributesByAttributes($attributes=array(), $terms=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$attributes || !$model || !$terms) return null;
        $sql="SELECT ";

        $attributesNames=array_keys($attributes);
        foreach($attributes as $name=>$attr){
            if($name!=end($attributesNames)){
                $sql.=$attr.", ";
            }else{
                $sql.=$attr;
            }
        }

        $sql.=" FROM `".DB_PREFIX.$model."` WHERE ";

        $attributesNames=array_keys($terms);
        foreach($terms as $name=>$attr){
            if($name!=end($attributesNames)){
                $sql.=$name." = '".$attr."' AND ";
            }else{
                $sql.=$name." = '".$attr."'";
            }
        }

        $query=$this->db->query($sql);

        if(!isset($query->rows) || !$query->rows) return false;

        return $query->rows;
    }

    public function save($data=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$data || !is_array($data) || !$model) return false;
        $sql="INSERT INTO `".DB_PREFIX.$model."` (";

        $size=sizeof($data)-1;
        $i=0;
        foreach(array_keys($data) as $name){
            if($i<$size){
                $sql.="".$name.", ";
            }else{
                $sql.="".$name.") VALUES (";
            }
            $i++;
        }

        $i=0;
        foreach($data as $value){
            if($i<$size){
                $sql.="'".$value."', ";
            }else{
                $sql.="'".$value."')";
            }
            $i++;
        }

        $this->db->query($sql);
        return true;
    }

    public function deleteByAttributes($data=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$data || !is_array($data) || !$model) return false;
        if($this->isEmpty) return false;
        $sql="DELETE FROM `".DB_PREFIX.$model."` WHERE ";

        $attributeNames=array_keys($data);
        foreach($data as $name=>$value){
            if($name!=end($attributeNames)){
                $sql.=$name." = '".(int)$value."' AND ";
            }else{
                $sql.=$name." = '".(int)$value."'";
            }
        }

        return $this->db->query($sql);
    }

    public function delete($pk, $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$pk){
            $pk=isset($this->id) ? $this->id : (isset($this->Id) ? $this->Id : $this->getPk());
        }

        if(!$pk || !$model) return false;

        return $this->db->query("DELETE FROM `".DB_PREFIX.$model."` WHERE ".$this->getPk($model)." = '".(int)$pk."'");
    }

    public function update($id=false, $data=array(), $model='')
    {
        if(!$id){
            $id=isset($this->id) ? $this->id : (isset($this->Id) ? $this->Id : $this->getPk());
        }
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$data || !is_array($data) || !$model) return false;
        if($this->isEmpty) return false;

        $sql="UPDATE `".DB_PREFIX.$model."` SET ";
        $i=0;
        foreach($data as $name=>$value){
            if($i<sizeof($data)-1){
                $sql.=$name." = '".$value."', ";
            }else{
                $sql.=$name." = '".$value."' WHERE ".$this->getPk($model)." = '".$id."'";
            }
            $i++;
        }

        $this->db->query($sql);
        return true;
    }

    protected function getColumnNames($model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$model || !$models=$this->findAll($model)) return false;
        $columns=is_array($models) ? $models[0] : $models;

        return array_keys($columns);
    }

    protected function getModelsTotal($model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        if(!$model) return null;

        $query=$this->db->query("SELECT COUNT(*) AS total FROM `".DB_PREFIX.$model."`");

        if(!isset($query->row['total'])) return false;
        return $query->row['total'];
    }

    public function findModelAttributesByPk($pk=0, $attributes=array(), $model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }

        if(!$pk){
            $pk=isset($this->id) ? $this->id : (isset($this->Id) ? $this->Id : $this->getPk());
        }
        if(!$pk || !$attributes || !$model) return null;
        $sql="SELECT ";

        $attributesNames=array_keys($attributes);
        foreach($attributes as $name=>$attr){
            if($name!=end($attributesNames)){
                $sql.=$attr.", ";
            }else{
                $sql.=$attr." FROM `".DB_PREFIX.$model."` WHERE ".$this->getPk($model)." = '".(int)$pk."'";
            }
        }

        $query=$this->db->query($sql);

        if(!isset($query->rows) || !$query->rows) return false;

        return $query->row;
    }

    private function getPk($model='')
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
        $primary='';
        if(strpos($model, '_') && $columns=$this->getColumnNames($model)) $primary=$columns[0];
        if(!$primary) $primary=$model.'_id';
        return $primary;
    }

    private function isEmpty($model)
    {
        if(!$model){
            $model=isset($this->tableName) ? $this->tableName : '';
        }
       if($this->getModelsTotal($model)) return false;
       else return true;
    }
}